package com.yunpuvip.sachet.rest.modular.auth.filter;

import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.RenderUtil;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.yunpuvip.sachet.modular.constant.ApplicationConstant;
import com.yunpuvip.sachet.modular.constant.CommonProperties;
import com.yunpuvip.sachet.modular.core.exception.RestException;
import com.yunpuvip.sachet.modular.core.exception.RestServiceExceptionEnum;
import com.yunpuvip.sachet.rest.config.properties.JwtProperties;
import com.yunpuvip.sachet.rest.modular.auth.util.JwtTokenUtil;
import io.jsonwebtoken.JwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;


/**
 * 对客户端请求的token验证过滤器
 *
 * @author fengshuonan
 * @Date 2017/8/24 14:04
 */

public class AuthFilter extends OncePerRequestFilter {
    private Logger log = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private JwtProperties jwtProperties;

    private String authToken;
    private static AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //只对post提交有效
        request.setCharacterEncoding("UTF-8");
        log.info("请求的URL：" + request.getRequestURL());

        log.info("进入过滤器" + request.getServletPath());
        final String requestHeader = request.getHeader(jwtProperties.getHeader());

        Enumeration enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            log.info(request.getServletPath() + "参数：" + paraName + ": " + request.getParameter(paraName));
        }
        String path = request.getServletPath();
        final String header = request.getHeader(jwtProperties.getHeader());
        if (AuthFilter.macth(path)) {
            //会被放过的请求
            chain.doFilter(request, response);
        } else {
            if (requestHeader != null && requestHeader.startsWith(ApplicationConstant.RequestParameter.AuthHead)) {
                authToken = requestHeader.substring(7);
                //验证token是否过期,包含了验证jwt是否正确
                try {
                    boolean flag = jwtTokenUtil.isTokenExpired(authToken);
                    if (flag) {
                        RenderUtil.renderJson(response, ResponseData.error(RestServiceExceptionEnum.TOKEN_EXPIRED.getCode(), RestServiceExceptionEnum.TOKEN_EXPIRED.getMessage()));
                        return;
                    }
                } catch (JwtException e) {
                    //有异常就是token解析失败
                    RenderUtil.renderJson(response, ResponseData.error(RestServiceExceptionEnum.TOKEN_ERROR.getCode(), RestServiceExceptionEnum.TOKEN_ERROR.getMessage()));
                    return;
                }
            } else {
                //header没有带Bearer字段
                RenderUtil.renderJson(response, ResponseData.error(RestServiceExceptionEnum.TOKEN_ERROR.getCode(), RestServiceExceptionEnum.TOKEN_ERROR.getMessage()));
                return;
            }
            chain.doFilter(request, response);
        }
    }

    /**
     * token验证
     *
     * @param header
     * @return
     */
    private boolean validateToken(String header, HttpServletResponse response) {
        log.info("Head:{}", header);
        String prefix = jwtProperties.getPrefix();
        //判断请求头的内容
        if (ToolUtil.isEmpty(header) || !header.startsWith(prefix)) {
            log.info("请求头异常");
            RenderUtil.renderJson(response, new RestException(RestServiceExceptionEnum.TOKEN_ERROR.getCode(), RestServiceExceptionEnum.TOKEN_ERROR.getMessage()));
            return false;
        }
        authToken = header.substring(prefix.length());
        log.info("用户的请求头:{}", authToken);
        if (ToolUtil.isEmpty(authToken)) {
            return false;
        }
        //验证token是否过期
        try {
            boolean flag = jwtTokenUtil.isTokenExpired(authToken);
            if (flag) {
                RenderUtil.renderJson(response, new RestException(RestServiceExceptionEnum.TOKEN_EXPIRED.getCode(), RestServiceExceptionEnum.TOKEN_EXPIRED.getMessage()));
                log.info("token过期");
                return false;
            }
        } catch (Exception e) {
            RenderUtil.renderJson(response, new RestException(RestServiceExceptionEnum.TOKEN_EXPIRED.getCode(), RestServiceExceptionEnum.TOKEN_EXPIRED.getMessage()));
            return false;
        }

        //判断token是有实际用户存在
//      sachetPlayer sachetPlayer = PlayerKit.getsachetPlayer(authToken);
//      if(ToolUtil.isEmpty(sachetPlayer)){
//          log.info("token无效");
//          return false;
//      }
        return true;

    }

    /**
     * 请求的过滤
     *
     * @param path
     * @return
     */
    private static boolean macth(String path) {
        for (String patten : CommonProperties.getInstance().notCertification) {
            if (patten.indexOf("*") > 0) {
                if (antPathMatcher.match(patten, path)) {
                    return true;
                }
            } else {
                if (patten.equals(path)) {
                    return true;
                }
            }
        }
        return false;
    }


}


